package com.itjin.health.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.crypto.digest.DigestUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.itjin.health.domain.dto.UserApprovalRequest;
import com.itjin.health.domain.dto.UserUpdateRequest;
import com.itjin.health.domain.entity.OfflineAssessmentAppointment;
import com.itjin.health.domain.entity.OnlineAssessmentAppointment;
import com.itjin.health.domain.entity.RehabilitationPlan;
import com.itjin.health.domain.entity.User;
import com.itjin.health.domain.vo.UserVO;
import com.itjin.health.exception.BusinessException;
import com.itjin.health.exception.ErrorCode;
import com.itjin.health.mapper.OfflineAssessmentAppointmentMapper;
import com.itjin.health.mapper.OnlineAssessmentAppointmentMapper;
import com.itjin.health.mapper.RehabilitationPlanMapper;
import com.itjin.health.mapper.UserMapper;
import com.itjin.health.service.AdminService;
import com.itjin.health.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
@Slf4j
public class AdminServiceImpl implements AdminService {

  /**
   * 超级管理员角色
   */
  private static final String SUPER_ADMIN_ROLE = "超级管理员";

  /**
   * 管理员角色
   */
  private static final String ADMIN_ROLE = "管理员";

  /**
   * 教师角色
   */
  private static final String TEACHER_ROLE = "教师";

  /**
   * 盐值，混淆密码
   */
  private static final String SALT = "itjin";

  @Resource
  private UserMapper userMapper;

  @Resource
  private RehabilitationPlanMapper rehabilitationPlanMapper;

  @Resource
  private OfflineAssessmentAppointmentMapper offlineAssessmentAppointmentMapper;

  @Resource
  private OnlineAssessmentAppointmentMapper onlineAssessmentAppointmentMapper;

  @Resource
  private UserService userService;

  @Resource
  private JavaMailSender mailSender;

  @Override
  public Page<UserVO> listUsersByPage(long current, long size, String role, String keyword) {
    // 创建分页对象
    Page<User> userPage = new Page<>(current, size);

    // 构建查询条件
    QueryWrapper<User> queryWrapper = new QueryWrapper<>();

    // 不查询密码字段
    queryWrapper.select(User.class, info -> !info.getColumn().equals("password"));

    // 根据角色筛选
    if (StringUtils.isNotBlank(role)) {
      queryWrapper.eq("role", role);
    }

    // 根据关键词搜索
    if (StringUtils.isNotBlank(keyword)) {
      queryWrapper.and(wrapper -> wrapper.like("username", keyword)
          .or()
          .like("student_number", keyword));
    }

    // 按创建时间降序排序
    queryWrapper.orderByDesc("created_at");

    // 执行查询
    userMapper.selectPage(userPage, queryWrapper);

    // 将结果转换为VO对象
    Page<UserVO> userVOPage = new Page<>(
        userPage.getCurrent(),
        userPage.getSize(),
        userPage.getTotal());

    List<UserVO> userVOList = userPage.getRecords().stream()
        .map(userService::getUserVO)
        .collect(Collectors.toList());

    userVOPage.setRecords(userVOList);

    return userVOPage;
  }

  @Override
  public List<UserVO> getPendingAccounts() {
    // 构建查询条件
    QueryWrapper<User> queryWrapper = new QueryWrapper<>();

    // 查询待审核的管理员和教师账号
    queryWrapper.eq("status", 2) // 使用status=2表示待审核状态
        .and(wrapper -> wrapper.eq("role", ADMIN_ROLE)
            .or()
            .eq("role", TEACHER_ROLE));

    log.info("待审核账号查询条件: {}", queryWrapper.getTargetSql());

    // 执行查询
    List<User> pendingUsers = userMapper.selectList(queryWrapper);

    // 记录查询结果
    log.info("待审核账号查询结果数量: {}", pendingUsers.size());
    pendingUsers
        .forEach(user -> log.info("待审核账号: id={}, role={}, status={}", user.getId(), user.getRole(), user.getStatus()));

    // 转换为VO对象
    return pendingUsers.stream()
        .map(userService::getUserVO)
        .collect(Collectors.toList());
  }

  @Override
  @Transactional
  public boolean approveUserAccount(UserApprovalRequest approvalRequest) {
    if (approvalRequest == null || approvalRequest.getUserId() == null) {
      throw new BusinessException(ErrorCode.PARAMS_ERROR);
    }

    Integer userId = approvalRequest.getUserId();
    Boolean approved = approvalRequest.getApproved();

    // 查询用户
    User user = userMapper.selectById(userId);
    if (user == null) {
      throw new BusinessException(ErrorCode.PARAMS_ERROR, "用户不存在");
    }

    // 检查用户是否为待审核状态
    if (user.getStatus() != 2) {
      throw new BusinessException(ErrorCode.PARAMS_ERROR, "该账号不在待审核状态");
    }

    // 检查是否为管理员或教师账号
    if (!ADMIN_ROLE.equals(user.getRole()) && !TEACHER_ROLE.equals(user.getRole())) {
      throw new BusinessException(ErrorCode.PARAMS_ERROR, "该账号不是管理员或教师账号");
    }

    // 更新用户状态
    UpdateWrapper<User> updateWrapper = new UpdateWrapper<>();
    updateWrapper.eq("id", userId);

    if (Boolean.TRUE.equals(approved)) {
      // 通过审核，启用账号
      updateWrapper.set("status", 0); // 正常状态
      userMapper.update(null, updateWrapper);

      // 发送审核通过邮件
      sendApprovalEmail(user, true, approvalRequest.getRemark());

      return true;
    } else {
      // 拒绝审核，将用户标记为删除状态
      updateWrapper.set("is_deleted", 1);
      userMapper.update(null, updateWrapper);

      // 发送审核拒绝邮件
      sendApprovalEmail(user, false, approvalRequest.getRemark());

      return true;
    }
  }

  @Override
  public boolean updateUser(UserUpdateRequest updateRequest) {
    if (updateRequest == null || updateRequest.getUserId() == null) {
      throw new BusinessException(ErrorCode.PARAMS_ERROR);
    }

    Integer userId = updateRequest.getUserId();

    // 查询用户是否存在
    User user = userMapper.selectById(userId);
    if (user == null) {
      throw new BusinessException(ErrorCode.PARAMS_ERROR, "用户不存在");
    }

    // 构建更新条件
    UpdateWrapper<User> updateWrapper = new UpdateWrapper<>();
    updateWrapper.eq("id", userId);

    // 更新用户名
    if (StringUtils.isNotBlank(updateRequest.getUsername())) {
      updateWrapper.set("username", updateRequest.getUsername());
    }

    // 更新邮箱（需要检查唯一性）
    if (StringUtils.isNotBlank(updateRequest.getEmail())) {
      String newEmail = updateRequest.getEmail();
      if (!newEmail.equals(user.getEmail())) {
        // 检查邮箱是否被其他用户使用
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("email", newEmail).ne("id", userId);
        long count = userMapper.selectCount(queryWrapper);
        if (count > 0) {
          throw new BusinessException(ErrorCode.PARAMS_ERROR, "邮箱已被其他用户使用");
        }
        updateWrapper.set("email", newEmail);
      }
    }

    // 更新电话（需要检查唯一性）
    if (StringUtils.isNotBlank(updateRequest.getPhone())) {
      String newPhone = updateRequest.getPhone();
      if (!newPhone.equals(user.getPhone())) {
        // 检查手机号是否被其他用户使用
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("phone", newPhone).ne("id", userId);
        long count = userMapper.selectCount(queryWrapper);
        if (count > 0) {
          throw new BusinessException(ErrorCode.PARAMS_ERROR, "手机号已被其他用户使用");
        }
        updateWrapper.set("phone", newPhone);
      }
    }

    // 更新角色
    if (StringUtils.isNotBlank(updateRequest.getRole())) {
      updateWrapper.set("role", updateRequest.getRole());
    }

    // 执行更新
    int result = userMapper.update(null, updateWrapper);
    return result > 0;
  }

  @Override
  public boolean deleteUser(Integer userId) {
    if (userId == null || userId <= 0) {
      throw new BusinessException(ErrorCode.PARAMS_ERROR);
    }

    // 查询用户
    User user = userMapper.selectById(userId);
    if (user == null) {
      throw new BusinessException(ErrorCode.PARAMS_ERROR, "用户不存在");
    }

    // 不允许删除超级管理员
    if (SUPER_ADMIN_ROLE.equals(user.getRole())) {
      throw new BusinessException(ErrorCode.PARAMS_ERROR, "不能删除超级管理员账号");
    }

    // 执行删除
    int result = userMapper.deleteById(userId);
    return result > 0;
  }

  @Override
  public String resetUserPassword(Integer userId) {
    if (userId == null || userId <= 0) {
      throw new BusinessException(ErrorCode.PARAMS_ERROR);
    }

    // 查询用户
    User user = userMapper.selectById(userId);
    if (user == null) {
      throw new BusinessException(ErrorCode.PARAMS_ERROR, "用户不存在");
    }

    // 使用固定的默认密码，而不是随机密码
    String newPassword = "Swust123";

    // 加密密码
    String encryptPassword = DigestUtil.md5Hex(SALT + newPassword);

    // 更新密码
    UpdateWrapper<User> updateWrapper = new UpdateWrapper<>();
    updateWrapper.eq("id", userId);
    updateWrapper.set("password", encryptPassword);

    userMapper.update(null, updateWrapper);

    // 发送密码重置邮件
    if (StringUtils.isNotBlank(user.getEmail())) {
      sendPasswordResetEmail(user, newPassword);
    }

    return newPassword;
  }

  @Override
  public boolean isAdmin(Integer userId) {
    if (userId == null || userId <= 0) {
      return false;
    }

    // 查询用户
    User user = userMapper.selectById(userId);
    if (user == null) {
      return false;
    }

    // 检查是否为管理员或超级管理员
    return ADMIN_ROLE.equals(user.getRole()) || SUPER_ADMIN_ROLE.equals(user.getRole())
        || TEACHER_ROLE.equals(user.getRole());
  }

  @Override
  public boolean isSuperAdmin(Integer userId) {
    if (userId == null || userId <= 0) {
      return false;
    }

    // 查询用户
    User user = userMapper.selectById(userId);
    if (user == null) {
      return false;
    }

    // 检查用户是否为超级管理员
    return SUPER_ADMIN_ROLE.equals(user.getRole());
  }

  /**
   * 判断用户是否为教师
   *
   * @param userId 用户ID
   * @return 是否为教师
   */
  @Override
  public boolean isTeacher(Integer userId) {
    if (userId == null || userId <= 0) {
      return false;
    }

    // 查询用户
    User user = userMapper.selectById(userId);
    if (user == null) {
      return false;
    }

    // 检查用户是否为教师
    return TEACHER_ROLE.equals(user.getRole());
  }

  /**
   * 检查用户是否拥有指定角色
   *
   * @param userId 用户ID
   * @param role   角色名称
   * @return 是否匹配指定角色
   */
  @Override
  public boolean checkUserRole(Integer userId, String role) {
    if (userId == null || userId <= 0 || StringUtils.isBlank(role)) {
      return false;
    }

    // 查询用户
    User user = userMapper.selectById(userId);
    if (user == null) {
      return false;
    }

    // 检查用户角色是否匹配
    return role.equals(user.getRole());
  }

  /**
   * 发送账号审核结果邮件
   * 
   * @param user     用户对象
   * @param approved 是否通过
   * @param remark   备注信息
   */
  private void sendApprovalEmail(User user, boolean approved, String remark) {
    if (user == null || StringUtils.isBlank(user.getEmail())) {
      return;
    }

    SimpleMailMessage message = new SimpleMailMessage();
    message.setTo(user.getEmail());
    message.setSubject("健康管理系统账号审核结果通知");

    StringBuilder content = new StringBuilder();
    content.append("尊敬的").append(user.getUsername()).append("：\n\n");

    if (approved) {
      content.append("恭喜您，您的").append(user.getRole()).append("账号申请已审核通过！\n");
      content.append("您现在可以使用学号：").append(user.getStudentNumber()).append(" 登录系统。\n");
    } else {
      content.append("很遗憾，您的").append(user.getRole()).append("账号申请未通过审核。\n");
      if (StringUtils.isNotBlank(remark)) {
        content.append("原因：").append(remark).append("\n");
      }
      content.append("如有疑问，请联系系统管理员。\n");
    }

    content.append("\n此邮件由系统自动发送，请勿回复。");

    message.setText(content.toString());

    try {
      mailSender.send(message);
    } catch (Exception e) {
      log.error("发送审核结果邮件失败", e);
    }
  }

  /**
   * 发送密码重置邮件
   * 
   * @param user        用户对象
   * @param newPassword 新密码
   */
  private void sendPasswordResetEmail(User user, String newPassword) {
    if (user == null || StringUtils.isBlank(user.getEmail())) {
      return;
    }

    SimpleMailMessage message = new SimpleMailMessage();
    message.setTo(user.getEmail());
    message.setSubject("健康管理系统密码重置通知");

    StringBuilder content = new StringBuilder();
    content.append("尊敬的").append(user.getUsername()).append("：\n\n");
    content.append("您的账号密码已被管理员重置，新密码为：").append(newPassword).append("\n");
    content.append("请使用新密码登录系统，并及时修改为您自己的密码。\n");
    content.append("\n此邮件由系统自动发送，请勿回复。");

    message.setText(content.toString());

    try {
      mailSender.send(message);
    } catch (Exception e) {
      log.error("发送密码重置邮件失败", e);
    }
  }

  @Override
  public Map<String, Object> getDashboardSummary() {
    Map<String, Object> summary = new HashMap<>();

    // 用户总数
    long totalUsers = userMapper.selectCount(null);

    // 学生数
    QueryWrapper<User> studentWrapper = new QueryWrapper<>();
    studentWrapper.eq("role", "学生");
    long studentCount = userMapper.selectCount(studentWrapper);

    // 教师数
    QueryWrapper<User> teacherWrapper = new QueryWrapper<>();
    teacherWrapper.eq("role", "教师");
    long teacherCount = userMapper.selectCount(teacherWrapper);

    // 管理员数
    QueryWrapper<User> adminWrapper = new QueryWrapper<>();
    adminWrapper.eq("role", "管理员");
    long adminCount = userMapper.selectCount(adminWrapper);

    // 待审核账号数
    QueryWrapper<User> pendingWrapper = new QueryWrapper<>();
    pendingWrapper.eq("status", 2);
    long pendingCount = userMapper.selectCount(pendingWrapper);

    // 今日新增用户数
    QueryWrapper<User> todayWrapper = new QueryWrapper<>();
    todayWrapper.ge("created_at", LocalDate.now().atStartOfDay());
    long todayNewUsers = userMapper.selectCount(todayWrapper);

    // 近7天用户注册趋势
    List<Map<String, Object>> userRegisterTrend = new ArrayList<>();
    LocalDate today = LocalDate.now();
    for (int i = 6; i >= 0; i--) {
      LocalDate date = today.minusDays(i);
      QueryWrapper<User> dayWrapper = new QueryWrapper<>();
      dayWrapper.ge("created_at", date.atStartOfDay());
      dayWrapper.lt("created_at", date.plusDays(1).atStartOfDay());
      long count = userMapper.selectCount(dayWrapper);

      Map<String, Object> dayData = new HashMap<>();
      dayData.put("date", date.toString());
      dayData.put("count", count);
      userRegisterTrend.add(dayData);
    }
    summary.put("userRegisterTrend", userRegisterTrend);

    // 近7天康复计划新增趋势
    List<Map<String, Object>> rehabPlanTrend = new ArrayList<>();
    for (int i = 6; i >= 0; i--) {
      LocalDate date = today.minusDays(i);
      QueryWrapper<RehabilitationPlan> dayWrapper = new QueryWrapper<>();
      dayWrapper.ge("created_at", date.atStartOfDay());
      dayWrapper.lt("created_at", date.plusDays(1).atStartOfDay());
      long count = rehabilitationPlanMapper.selectCount(dayWrapper);

      Map<String, Object> dayData = new HashMap<>();
      dayData.put("date", date.toString());
      dayData.put("count", count);
      rehabPlanTrend.add(dayData);
    }
    summary.put("rehabPlanTrend", rehabPlanTrend);

    // 近7天康复计划完成趋势
    List<Map<String, Object>> rehabPlanCompleteTrend = new ArrayList<>();
    for (int i = 6; i >= 0; i--) {
      LocalDate date = today.minusDays(i);
      QueryWrapper<RehabilitationPlan> dayWrapper = new QueryWrapper<>();
      dayWrapper.eq("status", 2); // 2-已完成
      dayWrapper.ge("updated_at", date.atStartOfDay());
      dayWrapper.lt("updated_at", date.plusDays(1).atStartOfDay());
      long count = rehabilitationPlanMapper.selectCount(dayWrapper);

      Map<String, Object> dayData = new HashMap<>();
      dayData.put("date", date.toString());
      dayData.put("count", count);
      rehabPlanCompleteTrend.add(dayData);
    }
    summary.put("rehabPlanCompleteTrend", rehabPlanCompleteTrend);

    // 近7天线下评估预约趋势
    List<Map<String, Object>> offlineAssessmentTrend = new ArrayList<>();
    for (int i = 6; i >= 0; i--) {
      LocalDate date = today.minusDays(i);
      QueryWrapper<OfflineAssessmentAppointment> dayWrapper = new QueryWrapper<>();
      dayWrapper.ge("created_at", date.atStartOfDay());
      dayWrapper.lt("created_at", date.plusDays(1).atStartOfDay());
      long count = offlineAssessmentAppointmentMapper.selectCount(dayWrapper);

      Map<String, Object> dayData = new HashMap<>();
      dayData.put("date", date.toString());
      dayData.put("count", count);
      offlineAssessmentTrend.add(dayData);
    }
    summary.put("offlineAssessmentTrend", offlineAssessmentTrend);

    // 近7天线上评估预约趋势
    List<Map<String, Object>> onlineAssessmentTrend = new ArrayList<>();
    for (int i = 6; i >= 0; i--) {
      LocalDate date = today.minusDays(i);
      QueryWrapper<OnlineAssessmentAppointment> dayWrapper = new QueryWrapper<>();
      dayWrapper.ge("created_at", date.atStartOfDay());
      dayWrapper.lt("created_at", date.plusDays(1).atStartOfDay());
      long count = onlineAssessmentAppointmentMapper.selectCount(dayWrapper);

      Map<String, Object> dayData = new HashMap<>();
      dayData.put("date", date.toString());
      dayData.put("count", count);
      onlineAssessmentTrend.add(dayData);
    }
    summary.put("onlineAssessmentTrend", onlineAssessmentTrend);

    summary.put("totalUsers", totalUsers);
    summary.put("studentCount", studentCount);
    summary.put("teacherCount", teacherCount);
    summary.put("adminCount", adminCount);
    summary.put("pendingCount", pendingCount);
    summary.put("todayNewUsers", todayNewUsers);

    // 你可以继续添加更多统计项

    return summary;
  }
}